package top.lyjwn.todo.common.sm;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.util.concurrent.atomic.AtomicReference;

public class SM2Util {


    private static SM2 sm2;

    private static synchronized SM2 getSm2() {
        if (sm2 == null) {
            sm2 = new SM2();
            sm2.setMode(SM2Engine.Mode.C1C2C3);

        }
        return sm2;
    }

    /**
     * 公钥加密
     *
     * @param cipherTxt
     * @return
     */
    public static String encrypt(String cipherTxt, String publicKey) {
        if (!StringUtils.hasText(cipherTxt)) {
            return cipherTxt;
        }
        String encryptStr = SmUtil.sm2(null, publicKey).encryptHex(cipherTxt, KeyType.PublicKey);
        //String encryptStr = getSm2().encryptBcd(cipherTxt, KeyType.PublicKey);
        return encryptStr;
    }

    /**
     * 私钥解密
     *
     * @param plainTxt
     * @return
     */
    public static String decrypt(String plainTxt, String privateKey) {

        if (!StringUtils.hasText(plainTxt)) {
            return plainTxt;
        }
//        AtomicReference<String> decryptStr = new AtomicReference<>(SmUtil.sm2(privateKey, null).decryptStr(plainTxt, KeyType.PrivateKey));
        String decryptStr = SmUtil.sm2(privateKey, null).decryptStr(plainTxt, KeyType.PrivateKey);
        return decryptStr;
    }

    /**
     * 生成一对 C1C2C3 格式的SM2密钥
     *
     * @return 处理结果
     */
    public static SM2KeyPair getSM2Key() {
        KeyPair pair = SecureUtil.generateKeyPair("SM2");
        byte[] privateKey = pair.getPrivate().getEncoded();
        byte[] publicKey = pair.getPublic().getEncoded();
//        AtomicReference<SM2KeyPair> sm2KeyPair = new AtomicReference<>(new SM2KeyPair(new String(Base64.encodeBase64(privateKey), StandardCharsets.UTF_8), new String(Base64.encodeBase64(publicKey), StandardCharsets.UTF_8)));
        SM2KeyPair sm2KeyPair = new SM2KeyPair(new String(Base64.encodeBase64(privateKey), StandardCharsets.UTF_8), new String(Base64.encodeBase64(publicKey), StandardCharsets.UTF_8));
        return sm2KeyPair;
    }

    public static void main(String[] args) {
        SM2KeyPair sm2Key = getSM2Key();
        System.out.println("私钥：" + sm2Key.getPrivateKey());
        System.out.println("公钥：" + sm2Key.getPublicKey());
        String privateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgdImL0xvAa6hgYESjxe59LBRAdCkDC+i9gJzs7W4SYMigCgYIKoEcz1UBgi2hRANCAARkpeMXLLsHUt3dcawQB3HNHLTGdi68OdvN/aepalwxOi+LcAx8i14Ek7OYlF6GT4eRQpfUGomkaAdZPObQ6jxh";//自己调用下面的getSM2Key生成
        /**公钥*/
        String publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEZKXjFyy7B1Ld3XGsEAdxzRy0xnYuvDnbzf2nqWpcMTovi3AMfIteBJOzmJRehk+HkUKX1BqJpGgHWTzm0Oo8YQ==";//自己调用下面的getSM2Key生成
        String mi = encrypt("{\"deptName\":\"放射科\",\"idCard\":\"332522196505047287\",\"patName\":\"张三\",\"hospitalName\":\"飞图影像中心ora\",\"stationIP\":\"192.168.0.123\",\"hospitalCode\":\"10001202\",\"timeStamp\":\"1650857296958\",\"visitId\":\"FT000026\",\"opName\":\"李医生\",\"requestId\":\"1221121121224\",\"patAge\":\"45岁\",\"requestCode\":\"001\",\"shareHR\":\"演示互认\",\"stationMAC\":\"00-16-EA-AE-3C-40\",\"deptCode\":\"rad\",\"opUid\":\"FT_D_001\"}",publicKey);
        System.out.println(mi);
        System.out.println(decrypt(mi,privateKey));
    }
}
